package services

import (
	"encoding/xml"
	"io/ioutil"
	"net/url"
	"strconv"
	"gitee.com/siruihuyu/appapi/game/core/wxpayment/utils"
	"github.com/astaxie/beego/logs"
)

var transfers = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"
var KEY = "5lI1xC9y5FWMbdkRizyBTxtjyd3UKu3K"
var mchID = "1498823442"

//付款订单
type WithdrawOrder struct {
	XMLName        xml.Name `xml:"xml"`
	MchAppid       string   `xml:"mch_appid"`  //
	Mchid          string   `xml:"mchid"`
	DeviceInfo     string   `xml:"device_info"`
	NonceStr       string   `xml:"nonce_str"`
	Sign           string   `xml:"sign"`
	PartnerTradeNo string   `xml:"partner_trade_no"`
	Openid         string   `xml:"openid"`
	CheckName      string   `xml:"check_name"`
	Amount         int64    `xml:"amount"`
	Desc           string   `xml:"desc"`
	SpbillCreateIp string   `xml:"spbill_create_ip"`
}

//付款订单结果
type WithdrawResult struct {
	ReturnCode     string `xml:"return_code"`
	ReturnMsg      string `xml:"return_msg"`
	ResultCode     string `xml:"result_code"`
	ErrCodeDes     string `xml:"err_code_des"`
	PaymentNo      string `xml:"payment_no"`
	PartnerTradeNo string `xml:"partner_trade_no"`
}

//付款，成功返回自定义订单号，微信订单号，true，失败返回错误信息，false
func WithdrawMoney(amount int64, appid, openid, partnerTradeNo, desc, clientIp string) (string, string, bool) {
	order := WithdrawOrder{}
	order.MchAppid = appid
	//order.Mchid = mchid
	order.Mchid = mchID
	order.Openid = openid
	order.Amount = amount
	order.Desc = desc
	order.PartnerTradeNo = partnerTradeNo
	order.DeviceInfo = "wx_mini" //小程序
	order.CheckName = "NO_CHECK" //NO_CHECK：不校验真实姓名 FORCE_CHECK：强校验真实姓名
	order.SpbillCreateIp = clientIp
	order.NonceStr = utils.GetRandomString()
	order.Sign = md5WithdrawOrder(order)
	xmlBody, _ := xml.MarshalIndent(order, " ", " ")
	resp, err := utils.SecurePost(transfers, xmlBody)
	if err != nil {
		return err.Error(), "", false
	}
	defer resp.Body.Close()
	bodyByte, _ := ioutil.ReadAll(resp.Body)
	var res WithdrawResult
	xmlerr := xml.Unmarshal(bodyByte, &res)

	logs.Info("WithdrawResult %s",string(bodyByte))
	if xmlerr != nil {
		return xmlerr.Error(), "", false
	}
	if res.ReturnCode == "SUCCESS" && res.ResultCode == "SUCCESS" {
		return res.PartnerTradeNo, res.PaymentNo, true
	}
	return res.ReturnMsg, res.ErrCodeDes, false
}

//md5签名
func md5WithdrawOrder(order WithdrawOrder) string {
	o := url.Values{}
	o.Add("mch_appid", order.MchAppid)
	o.Add("mchid", order.Mchid)
	o.Add("device_info", order.DeviceInfo)
	o.Add("partner_trade_no", order.PartnerTradeNo)
	o.Add("check_name", order.CheckName)
	o.Add("amount", strconv.FormatInt(order.Amount, 10))
	o.Add("spbill_create_ip", order.SpbillCreateIp)
	o.Add("desc", order.Desc)
	o.Add("nonce_str", order.NonceStr)
	o.Add("openid", order.Openid)
	r, _ := url.QueryUnescape(o.Encode())
	return utils.Md5([]byte(r + "&key=" + KEY))
}
